#ifndef NET_CONTROLLER_H
#define NET_CONTROLLER_H

#include "TCPManager.h"
#include "NetMessages.h"
#include <string>
#include <iostream>
#include <map>
#include <vector>

using namespace std;

/// struct for a single tcp client
struct SClient
{
	int id;
	TCPManager* tcp;
	string ip;
	unsigned short port;
};

typedef map <int, SClient*> ClientMap;

typedef vector <TCPManager*> TCPVector;

/// struct for a single tcp server
struct SServer
{
	int id;
	TCPManager* tcp;
	unsigned short port;
	TCPVector sockets;		/// all opened sockets
};

typedef map <int, SServer*> ServerMap;


/**
* \brief	Wrapper for TCPManager
*
* CNetControllerTCP wraps the TCPManager and manages multiple
* clients and servers. However, it allows one-way communication only:
* Clients can only send and servers can only receive.
*/
class CNetControllerTCP
{
public:
	CNetControllerTCP(void);
	~CNetControllerTCP(void);

	/**
	* \brief	Adds a single client to the controller.
	*
	* \param strIp	the server's ip address
	* \param usPort the port to use
	*
	* \return	The id for this client or 0 on error. Use this to send
	*			specifically for this client.
	*/
	int addClient(string strIp, unsigned short usPort);
	/// Removes the client with the specified id.
	void removeClient(int id);

	/// Adds a server to start listening on the given port (see addClient).
	int addServer(USHORT usPort);
	/// Removes the server with the specified id.
	void removeServer(int id);

	/// Sends the given data for all clients, returns true on success
	bool send(unsigned short usType, string strData);
	/// Sends the given data for the given client, returns true on success
	bool send(unsigned short usType, string strData, int nId);

	/**
	* \brief	Fetches the data of the given server and returns
	*			it as type and data.
	*
	* \param usType		return value, the message type
	* \param strData	return value, the actual message
	* \param nId		the server's id
	*
	* \return	true on success
	*/
	bool receive(unsigned short* usType, string* strData, int nId);
	/// accept new connections
	void accept();

private:
	/// Composes the complete message string from the given inputs.
	string createMessage(unsigned short usType, string strData);

	ClientMap mapClients;
	ServerMap mapServers;

	int nMaxClientId;		/// the highest given id number
	int nMaxServerId;		/// the highest given id number
};

#endif	// NET_CONTROLLER_H
